package tech.mhuang.pacebox.springboot.core.protocol.tree;

import tech.mhuang.pacebox.core.util.CollectionUtil;
import tech.mhuang.pacebox.core.util.StringUtil;
import tech.mhuang.pacebox.springboot.protocol.data.BaseTreeNode;

import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 树节点工具类
 *
 * @author mhuang
 * @since 1.1.2
 */
public class TreeNodeUtil {

    /**
     * 将当前列表数据转成封装成树状图数据
     *
     * @param nodeList 列表数据
     * @param <T>      类型
     * @return 树状图数据
     */
    public static <T extends BaseTreeNode> List<T> assembleTree(List<T> nodeList) {
        return assembleTree(null, nodeList);

    }

    /**
     * 根据id将树列表封装成树状图数据
     *
     * @param id       树id
     * @param nodeList 树列表
     * @param <T>      类型
     * @return 树状图数据
     */
    public static <T extends BaseTreeNode> List<T> assembleTree(String id, List<T> nodeList) {
        if (CollectionUtil.isEmpty(nodeList)) {
            return null;
        }
        //封装应答
        return nodeList.stream()
                //过滤掉id是父级
                .filter(node -> StringUtil.equals(id, node.getParentId()))
                //然后获取对应的节点数据
                .map(node -> assembleTreeChildren(node, nodeList)).sorted(Comparator.comparing(BaseTreeNode::getSorted)).collect(Collectors.toList());
    }

    /**
     * 根据某个节点将树列表封装成树状图数据
     *
     * @param node     树节点
     * @param nodeList 树列表
     * @param <T>      不确定类型
     * @return 树状图数据
     */
    public static <T extends BaseTreeNode> T assembleTreeChildren(T node, final List<T> nodeList) {
        if (CollectionUtil.isEmpty(nodeList)) {
            return node;
        }
        List<T> childrenList = nodeList.stream()
                //找到符合他的下级节点
                .filter(children -> StringUtil.equals(node.getId(), children.getParentId()))
                //在循环遍历下级的children
                .map(children -> assembleTreeChildren(children, nodeList)).sorted(Comparator.comparing(BaseTreeNode::getSorted)).collect(Collectors.toList());
        //放入到children中
        node.setChildren(childrenList);
        return node;
    }
}
